package jehc.cloud.iot.live.unvif.util;

import de.onvif.soap.OnvifDevice;
import de.onvif.soap.devices.PtzDevices;
import jehc.cloud.common.base.BaseResult;
import jehc.cloud.common.util.StringUtil;
import jehc.cloud.iot.live.unvif.UnVif;
import jehc.cloud.iot.live.unvif.entity.OnvifDeviceInfo;
import jehc.cloud.iot.live.unvif.entity.UnVifInfo;
import lombok.extern.slf4j.Slf4j;
import org.onvif.ver10.schema.PTZVector;
import org.onvif.ver10.schema.Profile;
import org.springframework.stereotype.Component;

import javax.xml.soap.SOAPException;
import java.net.ConnectException;
import java.util.List;

/**
 * @Desc
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Component
@Slf4j
public class UnVifUtil {

    /**
     * 登录设备
     * @param unVifInfo
     * @return
     */
    public static BaseResult login(UnVifInfo unVifInfo) {
        BaseResult baseResult = new BaseResult();
        OnvifDevice onvifDevice;
        if(null == unVifInfo){
            log.error("UnvifInfo为空");
            baseResult.setMessage("UnvifInfo为空");
            return baseResult;
        }
        if(StringUtil.isEmpty(unVifInfo.getDevice_id())){
            log.error("设备编号为空");
            baseResult.setMessage("设备编号为空");
            return baseResult;
        }
        if(StringUtil.isEmpty(unVifInfo.getIp())){
            log.error("ip为空");
            baseResult.setMessage("ip为空");
            return baseResult;
        }
        if(StringUtil.isEmpty(unVifInfo.getUserName())){
            log.error("摄像机登录名为空");
            baseResult.setMessage("摄像机登录名为空");
            return baseResult;
        }
        if(StringUtil.isEmpty(unVifInfo.getPassword())){
            log.error("摄像机密码为空");
            baseResult.setMessage("摄像机密码为空");
            return baseResult;
        }
        /**
         * 处理web端口非80
         */
        if(unVifInfo.getPort() != 80 && unVifInfo.getPort() != 0){
            unVifInfo.setIp(unVifInfo.getIp()+":"+unVifInfo.getPort());
        }
        try {
            OnvifDeviceInfo onvifDeviceInfo = new OnvifDeviceInfo();
            onvifDevice = new OnvifDevice(unVifInfo.getIp(), unVifInfo.getUserName(), unVifInfo.getPassword());
            String proToken = getToken(onvifDevice);
            onvifDeviceInfo.setOnvifDevice(onvifDevice);
            onvifDeviceInfo.setProfileToken(proToken);
            UnVif.OnvifDeviceCache.put(unVifInfo.getDevice_id(),onvifDeviceInfo);
        } catch (ConnectException | SOAPException e1) {
            log.error("没有连接到摄像头，请重试。");
            baseResult.setMessage("没有连接到摄像头！");
            return null;
        }
        baseResult.setMessage("连接摄像头成功！");
        log.info("连接摄像头成功！{}",unVifInfo.getDevice_id());
        return baseResult;
    }

    /**
     * 获取摄像机Token
     * @param onvifDevice
     * @return
     */
    public static String getToken(OnvifDevice onvifDevice){
        if(null == onvifDevice){
            log.error("OnvifDevice is null。");
            return null;
        }
        List<Profile> profileList = onvifDevice.getDevices().getProfiles();
        String profileToken = profileList.get(0).getToken();
        return profileToken;
    }

    /**
     *
     * @return
     */
    public BaseResult control(UnVifInfo unVifInfo){
        BaseResult baseResult;
        OnvifDeviceInfo onvifDeviceInfo = UnVif.getOnvifDevice(unVifInfo.getDevice_id());
        if(null == onvifDeviceInfo){
            login(unVifInfo);//登录
        }
        if(unVifInfo.getStart() == 1){
            baseResult = startPtzControl(unVifInfo);
        }else{
            baseResult = stopPtzControl(unVifInfo);
        }
        return baseResult;
    }

    /**
     * 云控
     * @param unVifInfo
     * @return
     */
    public BaseResult startPtzControl(UnVifInfo unVifInfo){
        BaseResult baseResult =  new BaseResult();
        OnvifDeviceInfo onvifDeviceInfo = UnVif.getOnvifDevice(unVifInfo.getDevice_id());
        if(null == onvifDeviceInfo){
            log.info("未能获取到OnvifDeviceInfo，{}",unVifInfo);
            baseResult.setMessage("未能获取到OnvifDeviceInfo！");
            return baseResult;
        }
        OnvifDevice onvifDevice = onvifDeviceInfo.getOnvifDevice();
        PtzDevices ptzDevices = onvifDevice.getPtz();
        /*获取当前位置 暂时用不到
        PTZVector position = ptzDevices.getStatus(unVifInfo.getDevice_id()).getPosition();
        float zoom = position.getZoom().getX();
        float x = (new Float(0.33)+position.getPanTilt().getX());
        float y =  (new Float(0.33)+position.getPanTilt().getY());
        */
        /* 屏蔽该代码
        if (!ptzDevices.isContinuosMoveSupported(onvifDeviceInfo.getProfileToken())){
            baseResult.setMessage("摄像头不支持云控！");
            return baseResult;
        }
        */
        Integer speed = unVifInfo.getPtzSpeed();
        float newSpeed = 0.1f;
        if(null == speed){
            newSpeed = 0.1f;
        }else if(speed == 1){
            newSpeed = 0.1f;
        }else if(speed == 2){
            newSpeed = 0.2f;
        }else if(speed == 3){
            newSpeed = 0.3f;
        }else if(speed == 4){
            newSpeed = 0.4f;
        }else if(speed == 5){
            newSpeed = 0.5f;
        }else{
            newSpeed = 0.1f;
        }
        boolean res = false;
        switch (unVifInfo.getPztType()) {
            case "TILT_UP":
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), 0f, newSpeed, 0);//上转
                break;
            case "TILT_DOWN":
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), 0, -newSpeed, 0);//下转
                break;
            case "PAN_LEFT":
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), -newSpeed, 0, 0);//左转
                break;
            case "PAN_RIGHT":
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), newSpeed, 0, 0);//右转
                break;
            case "UP_LEFT":
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), -newSpeed, newSpeed, 0);//左上转
                break;
            case "UP_RIGHT":
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), newSpeed, newSpeed, 0);//右上转
                break;
            case "DOWN_LEFT":
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), -newSpeed, -newSpeed, 0);//左下转
                break;
            case "DOWN_RIGHT":
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), newSpeed, -newSpeed, 0);//右下转
                break;
            case "ZOOM_IN":
                /*//放大缩小 需要获取原坐标
                PTZVector position = ptzDevices.getStatus(unVifInfo.getDevice_id()).getPosition();
                float zoom = position.getZoom().getX();
                float x = (position.getPanTilt().getX());
                float y =  (position.getPanTilt().getY());*/
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), 0, 0, newSpeed);//放大
                break;
            case "ZOOM_OUT":
                res = ptzDevices.continuousMove(onvifDeviceInfo.getProfileToken(), 0, 0, -newSpeed);//缩小
                break;
            default:
                log.info("未能获取到云控转动方式参数");
                break;
        }
        if(res){
            baseResult.setMessage("云控成功！");
        }else{
            baseResult.setMessage("云控失败！");
        }
        return baseResult;
    }

    /**
     * 停止云控
     * @param unVifInfo
     * @return
     */
    public BaseResult stopPtzControl(UnVifInfo unVifInfo){
        BaseResult baseResult =  new BaseResult();
        OnvifDeviceInfo onvifDeviceInfo = UnVif.getOnvifDevice(unVifInfo.getDevice_id());
        if(null == onvifDeviceInfo){
            return baseResult;
        }
        OnvifDevice onvifDevice = onvifDeviceInfo.getOnvifDevice();
        PtzDevices ptzDevices = onvifDevice.getPtz();
        boolean res = ptzDevices.stopMove(onvifDeviceInfo.getProfileToken());
        if(!res){
            log.info("停止摄像头失败！{}",unVifInfo);
            baseResult.setMessage("停止摄像头失败！");
            return baseResult;
        }
        return baseResult;
    }
}
